package entities;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.lang.reflect.Method;
import java.util.Map;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.File;

public class EntityManager {

	private static Map<String, List> AllInstance = new HashMap<String, List>();
	
	private static List<SessionRecord> SessionRecordInstances = new LinkedList<SessionRecord>();
	private static List<WorkoutSession> WorkoutSessionInstances = new LinkedList<WorkoutSession>();
	private static List<Report> ReportInstances = new LinkedList<Report>();
	private static List<Member> MemberInstances = new LinkedList<Member>();
	private static List<Staff> StaffInstances = new LinkedList<Staff>();
	private static List<CheckInDevice> CheckInDeviceInstances = new LinkedList<CheckInDevice>();
	private static List<WorkoutSchedule> WorkoutScheduleInstances = new LinkedList<WorkoutSchedule>();

	
	/* Put instances list into Map */
	static {
		AllInstance.put("SessionRecord", SessionRecordInstances);
		AllInstance.put("WorkoutSession", WorkoutSessionInstances);
		AllInstance.put("Report", ReportInstances);
		AllInstance.put("Member", MemberInstances);
		AllInstance.put("Staff", StaffInstances);
		AllInstance.put("CheckInDevice", CheckInDeviceInstances);
		AllInstance.put("WorkoutSchedule", WorkoutScheduleInstances);
	} 
		
	/* Save State */
	public static void save(File file) {
		
		try {
			
			ObjectOutputStream stateSave = new ObjectOutputStream(new FileOutputStream(file));
			
			stateSave.writeObject(SessionRecordInstances);
			stateSave.writeObject(WorkoutSessionInstances);
			stateSave.writeObject(ReportInstances);
			stateSave.writeObject(MemberInstances);
			stateSave.writeObject(StaffInstances);
			stateSave.writeObject(CheckInDeviceInstances);
			stateSave.writeObject(WorkoutScheduleInstances);
			
			stateSave.close();
					
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/* Load State */
	public static void load(File file) {
		
		try {
			
			ObjectInputStream stateLoad = new ObjectInputStream(new FileInputStream(file));
			
			try {
				
				SessionRecordInstances =  (List<SessionRecord>) stateLoad.readObject();
				AllInstance.put("SessionRecord", SessionRecordInstances);
				WorkoutSessionInstances =  (List<WorkoutSession>) stateLoad.readObject();
				AllInstance.put("WorkoutSession", WorkoutSessionInstances);
				ReportInstances =  (List<Report>) stateLoad.readObject();
				AllInstance.put("Report", ReportInstances);
				MemberInstances =  (List<Member>) stateLoad.readObject();
				AllInstance.put("Member", MemberInstances);
				StaffInstances =  (List<Staff>) stateLoad.readObject();
				AllInstance.put("Staff", StaffInstances);
				CheckInDeviceInstances =  (List<CheckInDevice>) stateLoad.readObject();
				AllInstance.put("CheckInDevice", CheckInDeviceInstances);
				WorkoutScheduleInstances =  (List<WorkoutSchedule>) stateLoad.readObject();
				AllInstance.put("WorkoutSchedule", WorkoutScheduleInstances);
				
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
		
	/* create object */  
	public static Object createObject(String Classifer) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method createObjectMethod = c.getDeclaredMethod("create" + Classifer + "Object");
			return createObjectMethod.invoke(c);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/* add object */  
	public static Object addObject(String Classifer, Object ob) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method addObjectMethod = c.getDeclaredMethod("add" + Classifer + "Object", Class.forName("entities." + Classifer));
			return  (boolean) addObjectMethod.invoke(c, ob);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}	
	
	/* add objects */  
	public static Object addObjects(String Classifer, List obs) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method addObjectsMethod = c.getDeclaredMethod("add" + Classifer + "Objects", Class.forName("java.util.List"));
			return  (boolean) addObjectsMethod.invoke(c, obs);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/* Release object */
	public static boolean deleteObject(String Classifer, Object ob) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method deleteObjectMethod = c.getDeclaredMethod("delete" + Classifer + "Object", Class.forName("entities." + Classifer));
			return  (boolean) deleteObjectMethod.invoke(c, ob);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}
	
	/* Release objects */
	public static boolean deleteObjects(String Classifer, List obs) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method deleteObjectMethod = c.getDeclaredMethod("delete" + Classifer + "Objects", Class.forName("java.util.List"));
			return  (boolean) deleteObjectMethod.invoke(c, obs);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}		 	
	
	 /* Get all objects belongs to same class */
	public static List getAllInstancesOf(String ClassName) {
			 return AllInstance.get(ClassName);
	}	

   /* Sub-create object */
	public static SessionRecord createSessionRecordObject() {
		SessionRecord o = new SessionRecord();
		return o;
	}
	
	public static boolean addSessionRecordObject(SessionRecord o) {
		return SessionRecordInstances.add(o);
	}
	
	public static boolean addSessionRecordObjects(List<SessionRecord> os) {
		return SessionRecordInstances.addAll(os);
	}
	
	public static boolean deleteSessionRecordObject(SessionRecord o) {
		return SessionRecordInstances.remove(o);
	}
	
	public static boolean deleteSessionRecordObjects(List<SessionRecord> os) {
		return SessionRecordInstances.removeAll(os);
	}
	public static WorkoutSession createWorkoutSessionObject() {
		WorkoutSession o = new WorkoutSession();
		return o;
	}
	
	public static boolean addWorkoutSessionObject(WorkoutSession o) {
		return WorkoutSessionInstances.add(o);
	}
	
	public static boolean addWorkoutSessionObjects(List<WorkoutSession> os) {
		return WorkoutSessionInstances.addAll(os);
	}
	
	public static boolean deleteWorkoutSessionObject(WorkoutSession o) {
		return WorkoutSessionInstances.remove(o);
	}
	
	public static boolean deleteWorkoutSessionObjects(List<WorkoutSession> os) {
		return WorkoutSessionInstances.removeAll(os);
	}
	public static Report createReportObject() {
		Report o = new Report();
		return o;
	}
	
	public static boolean addReportObject(Report o) {
		return ReportInstances.add(o);
	}
	
	public static boolean addReportObjects(List<Report> os) {
		return ReportInstances.addAll(os);
	}
	
	public static boolean deleteReportObject(Report o) {
		return ReportInstances.remove(o);
	}
	
	public static boolean deleteReportObjects(List<Report> os) {
		return ReportInstances.removeAll(os);
	}
	public static Member createMemberObject() {
		Member o = new Member();
		return o;
	}
	
	public static boolean addMemberObject(Member o) {
		return MemberInstances.add(o);
	}
	
	public static boolean addMemberObjects(List<Member> os) {
		return MemberInstances.addAll(os);
	}
	
	public static boolean deleteMemberObject(Member o) {
		return MemberInstances.remove(o);
	}
	
	public static boolean deleteMemberObjects(List<Member> os) {
		return MemberInstances.removeAll(os);
	}
	public static Staff createStaffObject() {
		Staff o = new Staff();
		return o;
	}
	
	public static boolean addStaffObject(Staff o) {
		return StaffInstances.add(o);
	}
	
	public static boolean addStaffObjects(List<Staff> os) {
		return StaffInstances.addAll(os);
	}
	
	public static boolean deleteStaffObject(Staff o) {
		return StaffInstances.remove(o);
	}
	
	public static boolean deleteStaffObjects(List<Staff> os) {
		return StaffInstances.removeAll(os);
	}
	public static CheckInDevice createCheckInDeviceObject() {
		CheckInDevice o = new CheckInDevice();
		return o;
	}
	
	public static boolean addCheckInDeviceObject(CheckInDevice o) {
		return CheckInDeviceInstances.add(o);
	}
	
	public static boolean addCheckInDeviceObjects(List<CheckInDevice> os) {
		return CheckInDeviceInstances.addAll(os);
	}
	
	public static boolean deleteCheckInDeviceObject(CheckInDevice o) {
		return CheckInDeviceInstances.remove(o);
	}
	
	public static boolean deleteCheckInDeviceObjects(List<CheckInDevice> os) {
		return CheckInDeviceInstances.removeAll(os);
	}
	public static WorkoutSchedule createWorkoutScheduleObject() {
		WorkoutSchedule o = new WorkoutSchedule();
		return o;
	}
	
	public static boolean addWorkoutScheduleObject(WorkoutSchedule o) {
		return WorkoutScheduleInstances.add(o);
	}
	
	public static boolean addWorkoutScheduleObjects(List<WorkoutSchedule> os) {
		return WorkoutScheduleInstances.addAll(os);
	}
	
	public static boolean deleteWorkoutScheduleObject(WorkoutSchedule o) {
		return WorkoutScheduleInstances.remove(o);
	}
	
	public static boolean deleteWorkoutScheduleObjects(List<WorkoutSchedule> os) {
		return WorkoutScheduleInstances.removeAll(os);
	}
  
}

